package com.file.parser;

import com.file.bo.ResponseData;
import com.file.bo.mail.NJCB;
import com.file.bo.mail.NJCBTran;
import com.file.constant.ErrorCode;
import com.file.util.JsonUtils;
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;

/**
 * 丰巢-南京银行的pdf解析类
 * @author v_wbstlu
 * @date 2023-10-30
 */
@Slf4j
public class NJCBPdfParser extends BasePdfParser {

	public ResponseData<String> parseNJCBPdfToJson(String daId, String filePath) {
		log.info("parseNJCBPdfToJson started, daId:{}", daId);
		String json = null;

		try {
			NJCB njcb = parseNJCBPdf(filePath);
			json = JsonUtils.convertObjectToJson(njcb);
		} catch (Exception e) {
			log.error("OnError|{}||{}|{}|{}|{}", ErrorCode.FILE_PARSE_EXCEPTION.getCode(), daId, "", "", "parseNJCBPdfToJson failed", e);
			return new ResponseData<String>(json, ErrorCode.FILE_PARSE_EXCEPTION.getCode(),
					ErrorCode.FILE_PARSE_EXCEPTION.getMsg());
		}

		log.info("parseNJCBPdfToJson completed, daId:{}", daId);
		return new ResponseData<String>(json, ErrorCode.SUCCESS.getCode(), ErrorCode.SUCCESS.getMsg());
	}

	private NJCB parseNJCBPdf(String filePath) {
        NJCB njcb = parseNCJBHeader(filePath);
		List<NJCBTran> njcbTrans = parseNJCBTrans(filePath);

        njcb.setNjcbTrans(njcbTrans);
//		log.info("njcb = " + njcb);
		return njcb;
	}

	private NJCB parseNCJBHeader(String filePath) {
        NJCB ncjb = new NJCB();
		String pdfHeaderText = parsePdfHeaderText2(filePath);
		pdfHeaderText = pdfHeaderText.substring(pdfHeaderText.indexOf("户    名"), pdfHeaderText.indexOf("Period Application Time"));

		String accountName = pdfHeaderText.substring(pdfHeaderText.indexOf("户    名：") + 7, pdfHeaderText.indexOf("账    号：")).replaceAll(" ", "").trim();//NOSONAR
		String accountNo = pdfHeaderText.substring(pdfHeaderText.indexOf("账    号：") + 7, pdfHeaderText.indexOf("Name Account No账户类型：")).replaceAll(" ", "").trim();//NOSONAR
		String accountType = pdfHeaderText.substring(pdfHeaderText.indexOf("Name Account No账户类型：") + 20, pdfHeaderText.indexOf("开 户 行：")).replaceAll(" ", "").trim();//NOSONAR
		String subBranch = pdfHeaderText.substring(pdfHeaderText.indexOf("开 户 行：") + 7, pdfHeaderText.indexOf("Account Type Sub Branch起止日期：")).replaceAll(" ", "").trim();//NOSONAR
		String transDetailPeriod =  pdfHeaderText.substring(pdfHeaderText.indexOf("Account Type Sub Branch起止日期：") + 28, pdfHeaderText.indexOf("申请时间：")).replaceAll(" ", "").trim();//NOSONAR
		String applyDateTime = pdfHeaderText.substring(pdfHeaderText.indexOf("申请时间：") + 6).replaceAll(" ", "").trim();//NOSONAR

        ncjb.setAccountName(accountName);
        ncjb.setAccountNo(accountNo);
        ncjb.setAccountType(accountType);
        ncjb.setSubBranch(subBranch);
        ncjb.setTransDetailPeriod(transDetailPeriod);
        ncjb.setApplyDateTime(applyDateTime);

		return ncjb;
	}

	private List<NJCBTran> parseNJCBTrans(String filePath) {
		List<NJCBTran> njcbTrans = new ArrayList<>();

		String transText = getPdfTextByStripper(filePath);
		if (Strings.isNullOrEmpty(transText)) {
			return njcbTrans;
		}

		List<List<String>> tranFieldsList = parseTransTextToTranFieldsList(transText);

        // 交易日期
        String tranDate = "";
        // 币种
        String currency = "";
        // 交易金额
        String tranAmt = "";
        // 余额
        String balance = "";
        // 交易摘要
        String tranSummary = "";
        Boolean tranSummaryStatus = false;
        // 对手信息
        String counterPartyInfo = "";
        // 每行的记录是否读取完成
        Boolean rowResult = false;
		for (int i = 0; i < tranFieldsList.size(); i++) {
            List<String> strings = tranFieldsList.get(i);
			if (StringUtils.isBlank(strings.get(0)) || Objects.equals("SCAN THE QR CODE BELOW.", strings.get(0)) || strings.get(0).contains("平安银行个人账户交易明细清单") || i+1 == tranFieldsList.size()) {
                continue;
            }
             log.info(strings.toString());
            // 下一行的数据
            List<String> nextStrings = tranFieldsList.get(i + 1);

            String[] contents = strings.get(0).split(" ");
            if (StringUtils.isBlank(contents[0]) || StringUtils.equals(contents[0], "Page") || contents[0].matches("[0-9]\\/[0-9]")) {
                continue;
            }

            // 完整的解析
            if (contents.length == 6 || contents.length == 5) {
                if (Pattern.matches("\\d{8}", contents[0])) {
                    tranDate = contents[0];
                    currency = contents[1];
                    tranAmt = contents[2];
                    balance = contents[3];
                    tranSummary = contents[4];
                    if (contents.length == 6) {
                        counterPartyInfo = contents[5];
                        tranSummaryStatus = true;
                        if (nextStrings.get(0).length() > 24) {
                            rowResult = true;
                        }
                    }
                    if (contents.length == 5 && nextStrings.get(0).length() > 24) {
                        rowResult = true;
                    }

                }
            } else {
                // 交易摘要
                if (StringUtils.isNotBlank(tranDate) && Boolean.FALSE.equals(tranSummaryStatus)) {
                    tranSummary += strings.get(0);
                    if (strings.get(0).length() < nextStrings.get(0).length() && nextStrings.get(0).length() < 24) {
                        tranSummaryStatus = true;
                        continue;
                    } else {
                        rowResult = true;
                    }
                }

                // 对手信息
                if (Boolean.TRUE.equals(tranSummaryStatus)) {
                    counterPartyInfo += strings.get(0);
                    if (!CollectionUtils.isEmpty(nextStrings) && (nextStrings.get(0).length() > 24 || nextStrings.get(0).contains("————————————————————") || Boolean.TRUE.equals(nextStrings.get(0).matches("[0-9]\\/[0-9]")))) {
                        rowResult = true;
                    }
                }

            }

            // 解析完成
            if (Boolean.TRUE.equals(rowResult)) {
                NJCBTran njcbTran = new NJCBTran();
                njcbTran.setTranDate(tranDate);
                njcbTran.setCurrency(currency);
                njcbTran.setTranAmt(tranAmt);
                njcbTran.setBalance(balance);
                njcbTran.setTranSummary(tranSummary);
                njcbTran.setCounterPartyInfo(counterPartyInfo);
                njcbTrans.add(njcbTran);
                rowResult = false;
                tranDate = "";
                currency = "";
                tranAmt = "";
                balance = "";
                tranSummary = "";
                tranSummaryStatus = false;
                counterPartyInfo = "";

            }

		}
		return njcbTrans;
	}

	@Override
    public String getPdfTextByStripper(String filePath) {
		String pdfText = "";
		try (PDDocument pdDocument = PDDocument.load(new File(filePath))) {
			PDFTextStripper stripper = new PDFTextStripper();
			stripper.setSortByPosition(false);
			stripper.setStartPage(1);
			stripper.setEndPage(pdDocument.getNumberOfPages());
			pdfText = stripper.getText(pdDocument);
		} catch (Exception e) {
			log.error("OnError|{}||{}|{}|{}|{}", ErrorCode.FILE_PARSE_EXCEPTION.getCode(), "", "", "", "getPdfTextByStripper failed", e);
			throw new RuntimeException(e);
		}
		return pdfText;
	}

	public static void main(String[] args) {
		NJCBPdfParser njcbPdfParser = new NJCBPdfParser();
		NJCB njcb = njcbPdfParser.parseNJCBPdf("D:\\data\\南京银行交易明细 8.pdf");
		String json = JsonUtils.convertObjectToJson(njcb);
        System.out.println(json);
	}

}
